Next | Prev | Up | Top | Contents | Index

Entry Point open()

The kernel calls a device driver's pfxopen() entry when a process executes the open() system call on any device special file (see the open(2) reference page). It is also called when a process executes the mount() system call on a block device (see the mount(2) reference page). ( For the pfxopen() entry point of a STREAMS driver, see "Entry Point open()".)

The prototype of pfxopen() is as follows:

int pfxopen(dev_t *devp, int oflag, int otyp, cred_t *crp);

The argument values are

*devp Pointer to a dev_t value from which you can extract both the major and minor device numbers.
otypAn integer flag specifying the source of the call: a user process opening a character device or block device, or another driver.
oflagFlag bits specifying user mode options on the open() call.
crpA cred_t object--an opaque structure for use in authentication. Standard access privileges to the special device file have already been verified.

Note: When the driver's pfxdevflag entry contains D_OLD or when pfxdevflag is not defined, the first argument to pfxopen() is a dev_t value, not a pointer to a dev_t value. See "Flag D_OLD". In general, the driver is expected to verify that this user process is permitted access in the way specified in otyp (reading, writing, or both) for the device specified in *devp. If access is not allowable, the driver returns a nonzero error code from sys/errno.h, for example ENOMEM or EBUSY.


Use of the Device Number

When the driver supports a single device with no logical unit divisions, the device number is of little interest except for diagnostic displays. When the driver supports multiple devices, or a device with multiple logical units, the minor device number is the key to locating the device information. The device number can also encode device options, as discussed under "Minor Device Number".

When the driver supports the pfxedtinit() entry, the driver needs a way to associate the different edt_t structures passed to pfxedtinit() with the device numbers passed to pfxopen() and other routines. One solution is to require that the ctlr= value from the VECTOR statement--which is passed in the e_ctlr field of edt_t--must be the same as the device minor number.


Use of the Open Type

The otyp flag distinguishes between the following possible sources of this call to pfxopen() (the constants are defined in sys/open.h).

Typically a driver is written only to be a character driver or a block driver, and can be called only through the switch table for that type of device. When this is the case, the otyp value has little use.

It is possible to have the same driver treated as both block and character, in which case the driver needs to know whether the open() call addressed a block or character special device. It is possible for a block device to support different partitions with different uses, in which case the driver might need to record the fact that a device has been mounted, or opened as a swap device.

With all open types except OTYP_LYR, pfxopen() is called for every open or mount operation, but pfxclose() is called only when the last close or unmount occurs. The OTYP_LYR feature is used almost exclusively by drivers distributed with IRIX, like the host adapter SCSI driver (see "Host Adapter Concepts"). For each open of this type, there is one call to pfxclose().


Use of the Open Flag

The interpretation of the open mode flags is up to the designer of the driver. Four modes can be requested (declared in sys/file.h):

FREADInput access wanted.
FWRITEOutput access wanted (both FREAD and FWRITE may be set, corresponding to O_RDWR mode).
FNDELAY or FNONBLOCKReturn at once, do not sleep if the open cannot be done immediately.
FEXCLRequest exclusive use of the device.

You decide which of the flags have meaning with respect to the abilities of this device. You can return an EINVAL error when an unsupported mode is requested.

A key decision is whether the device can be opened only by one process at a time, or by multiple processes. If multiple opens are supported, a process can still request exclusive access with the FEXCL mode.

When the device can be used by only one process, or when FEXCL access is supported, the driver must keep track of the fact that the device is open. When the device is busy, the driver can test the FNDELAY and FNONBLOCK flags; if either is set, it can return EBUSY. Otherwise, the driver should sleep until the device is free; this requires coordination with the pfxclose() entry point.


Use of the cred_t Object

The cred_t object passed to pfxopen(), pfxclose(), and pfxioctl() can be used with the drv_priv() function to find out if the effective calling user ID is privileged or not (see the drv_priv(D3) reference page). Do not examine the object in detail, since its contents are subject to change from release to release.


Saving the Size of a Block Device

In a block device driver, the pfxsize() entry point will be called soon after pfxopen() (see "Entry Point size()"). It is typically best to calculate or read the device capacity at open time, and save it to be reported from pfxsize().


Saving the User ABI

If your driver is, or might be, compiled to the 64-bit model for use with a 64-bit IRIX kernel, and if it supports the pfxioctl() or pfxpoll() entry points, the driver should test and save the user process's programming model during an open. For details, see "Handling 32-Bit and 64-Bit Execution Models".


Next | Prev | Up | Top | Contents | Index